package com.sso.server.controller;

import com.sso.server.core.model.SsoLoginType;
import com.sso.core.util.StringUtils;
import com.sso.server.config.SsoConfig;
import com.sso.server.service.SmsService;
import com.sso.server.util.ImgUtil;
import com.sso.server.core.model.UserInfo;
import com.sso.server.core.result.ReturnData;
import com.sso.server.service.UserService;
import com.sso.core.conf.SSOConf;
import com.sso.core.login.SsoWebLoginHelper;
import com.sso.core.store.SsoLoginStore;
import com.sso.core.user.SsoUser;
import com.sso.core.store.SsoSessionIdHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * sso server (for web)
 */
@Controller
public class WebController {

    private static final Logger logger = LogManager.getLogger(WebController.class);


    @Autowired
    private UserService userService;
    @Autowired
    private SmsService smsService;

    @Value("${sso.sms.login.enabled}")
    private String smsEnabled;


    @RequestMapping("/")
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        SsoUser ssoUser = SsoWebLoginHelper.loginCheck(request, response);
        if (ssoUser == null) {
            return "redirect:/login";
        } else {
            model.addAttribute("username", ssoUser.getUsername());
            return "index";
        }
    }


    /**
     * @param model
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(SSOConf.SSO_LOGIN)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {

        SsoUser ssoUser = SsoWebLoginHelper.loginCheck(request, response);
        if (ssoUser != null) {

            String redirectUrl = request.getParameter(SSOConf.REDIRECT_URL);
            if (redirectUrl != null && redirectUrl.trim().length() > 0) {

                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                String redirectUrlFinal = redirectUrl + "?" + SSOConf.SSO_SESSIONID + "=" + sessionId;
                ;

                return "redirect:" + redirectUrlFinal;
            } else {
                return "redirect:/";
            }
        }
        model.addAttribute(SSOConf.SMS_ENABLED,smsEnabled);
        model.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
        return "login";
    }

    /**
     *
     * @param request
     * @param response
     * @param redirectAttributes
     * @param username account name or mobile
     * @param password
     * @param code
     * @param loginType
     * @return
     */
    @RequestMapping("/doLogin")
    public String doLogin(HttpServletRequest request,
                          HttpServletResponse response,
                          RedirectAttributes redirectAttributes,
                          String username,
                          String password,
                          String code,
                          String loginType,
                          String mobile,
                          String phoneCode) {
        if(loginType!=null){
            redirectAttributes.addFlashAttribute("loginType",  loginType);
        }

        ReturnData<UserInfo> result;
        if(SsoLoginType.SMS.getValue().equals(loginType)){

            String dbCode=SsoLoginStore.getSmsCode(mobile);
            if(!phoneCode.equals(dbCode)){
                redirectAttributes.addFlashAttribute("errorMsg",  "手机验证码错误！");
                if (StringUtils.isNotNull(mobile )) {
                    redirectAttributes.addFlashAttribute("mobile", mobile);
                }
                redirectAttributes.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
                return "redirect:/login";
            }

             result = userService.findUserByMobile(mobile);
            if(result==null){
                redirectAttributes.addFlashAttribute("errorMsg",  "手机号码错误！");
                if (StringUtils.isNotNull(mobile )) {
                    redirectAttributes.addFlashAttribute("mobile", mobile);
                }
                redirectAttributes.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
                return "redirect:/login";
            }


        }else{
            String kaptchaCode= (String) request.getSession().getAttribute(SSOConf.KAPTCHA_CODE);
            code=code.toUpperCase();
            if(!code.equals(kaptchaCode)){
                redirectAttributes.addFlashAttribute("errorMsg",  "验证码错误！");

                if (StringUtils.isNotNull(username)) {
                    redirectAttributes.addFlashAttribute("username", username);
                }
                redirectAttributes.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
                return "redirect:/login";
            }

            // valid login
            result = userService.findUser(username, password);
        }


        if (result.getCode() != ReturnData.SUCCESS_CODE) {
            redirectAttributes.addFlashAttribute("errorMsg", result.getMsg());
            if (username != null) {
                redirectAttributes.addFlashAttribute("username", username);
            }
            redirectAttributes.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
            return "redirect:/login";
        }

        SsoUser ssoUser = new SsoUser();
        ssoUser.setUsername(result.getData().getUsername());
        ssoUser.setId(result.getData().getId());
        ssoUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        ssoUser.setExpireMinute(SsoLoginStore.getRedisExpireMinute());
        ssoUser.setExpireFreshTime(System.currentTimeMillis());


        String sessionId = SsoSessionIdHelper.makeSessionId(ssoUser);
        SsoWebLoginHelper.login(response, sessionId, ssoUser, SsoConfig.cookieDomain);
        redirectAttributes.addFlashAttribute("username", ssoUser.getUsername());

        String redirectUrl = request.getParameter(SSOConf.REDIRECT_URL);
        if (redirectUrl != null && redirectUrl.trim().length() > 0) {
            String redirectUrlFinal = redirectUrl + "?" + SSOConf.SSO_SESSIONID + "=" + sessionId;
            return "redirect:" + redirectUrlFinal;
        } else {
            return "redirect:/";
        }

    }

    /**
     * Logout
     *
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(SSOConf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {

        SsoWebLoginHelper.logout(request, response);
        redirectAttributes.addAttribute(SSOConf.REDIRECT_URL, request.getParameter(SSOConf.REDIRECT_URL));
        return "redirect:/login";
    }


    /**
     * get login valid code
     * @param response
     * @param request
     */
    @GetMapping(path = "/getKaptcha")
    public void getKaptcha(HttpServletResponse response, HttpServletRequest request) {
         ImgUtil.genKaptcha(response,request);
    }

    /**
     * send sms valid code
     * @param mobile
     */
    @PostMapping(path = "/sendSms")
    @ResponseBody
    public ReturnData<String> sendSms(HttpServletRequest request,String code,String mobile) {

        String kaptchaCode= (String) request.getSession().getAttribute(SSOConf.KAPTCHA_CODE);
        code=code.toUpperCase();
        if(!code.equals(kaptchaCode)){
            return ReturnData.FAIL("验证码错误！");

        }

        String r= smsService.sendMsg(mobile);

        return ReturnData.SUCCESS();

    }





}
